package se.webbzon.boltzmann.minigame.page;

import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

import se.webbzon.boltzmann.input.Button;
import se.webbzon.boltzmann.input.Input;
import se.webbzon.boltzmann.input.InputListener;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldCameraPane;
import se.webbzon.oschi01.worldobject.WorldObject;

public class DefaultPage extends WorldObject implements Page {
	
	// The 2-dimensional depth of this page.
	private static final int depth = -1;
	
	// The layout of this page
	private final PageLayout layout;
	
	// The input controlling this page
	private final Input input;
	
	// The input listener of this page
	private final InputListener listener;
	
	// A list of all the info items of this page
	private final List<PageItem> items;
	
	// Whatever the page is visible
	private boolean visible;
	
	// The vertical top position of the page
	private int yTop;
	
	/*============================================================
	Constructors
	============================================================*/

	public DefaultPage(PageLayout layout, Input input) {
		super(WorldObject.onCreate + WorldObject.onStep + WorldObject.onDestroy + WorldObject.onPostDraw, depth);
		this.layout = layout;
		this.input = input;
		items = new ArrayList<PageItem>();
		listener = new InputListenerImpl();
		yTop = 32;
		visible = true;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public boolean isVisible() {
		return visible;
	}
	
	@Override public void setVisible(boolean visible) {
		this.visible = visible;
	}
	
	@Override public boolean addItem(PageItem item) {
		return items.add(item);
	}
	
	@Override public boolean removeItem(PageItem item) {
		return items.remove(item);
	}
	
	@Override public void clearItems() {
		items.clear();
	}
	
	@Override public int items() {
		return items.size();
	}
	
	@Override public PageItem getItem(int n) {
		return items.get(n);
	}
	
	@Override public int getYTop() {
		return yTop;
	}
	
	@Override public void setYTop(int y) {
		if (y > 128)
			yTop = 128;
		else if (y + getHeight() < 128)
			yTop = 128 - getHeight();
		else
			yTop = y;
	}
	
	@Override public boolean atBottom() {
		return yTop == 128 - getHeight();
	}
	
	@Override public boolean atTop() {
		return yTop == 128;
	}
	
	@Override public int getHeight() {
		int h = 0;
		for (PageItem item : items) {
			h += item.getHeight();
		}
		return h;
	}
	
	@Override public void onCreate(WorldArea world) {
		input.addListener(listener);
	}
	
	@Override public void onStep(WorldArea world) {
		for (int i = 0; i < items(); i++) {
			items.get(i).onStep(this);
		}
	}

	@Override public void onDestroy(WorldArea world) {
		input.removeListener(listener);
	}

	@Override public void onPostDraw(WorldArea world, WorldCameraPane hud) {
		if (!isVisible())
			return;
		final Dimension d = new Dimension();
		final int[] footers = new int[items.size()+1];
		int index = 1;
		hud.getLayer().getDimension(d);
		footers[0] = getYTop();
		for (PageItem item : items) {
			footers[index] += footers[index-1] + item.getHeight() + layout.getItemSpacing();
			index++;
		}
		
		// Draw background
		final int y = footers[0]-4;
		final int h = footers[index-1] - y + 4;
		hud.setColor(Color.white);
		hud.setTransparency(0.9f);
		hud.fillRect(8, y, d.width-16, h);
		hud.setTransparency(1f);
		hud.setColor(Color.blue);
		hud.drawRect(8, y, d.width-16, h);
		
		// Draw items
		index = 0;
		for (PageItem item : items) {
			item.draw(hud, 8, footers[index++]);
		}
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** This method is invoked when the user scrolls the page 
	 * upwards. **/
	protected void onMoveUp() {
		setYTop(getYTop() + 64);
	}
	
	/** This method is invoked when the user scrolls the page 
	 * downwards. **/
	protected void onMoveDown() {
		setYTop(getYTop() - 64);
	}
	
	/** Returns the input associated with this information page. **/
	protected Input getInput() {
		return input;
	}

	/*============================================================
	Private Methods
	============================================================*/
	
	private final class InputListenerImpl implements InputListener {

		@Override public void primaryAxisChanged(Input input, double direction, double value) {};

		@Override public void secondaryAxisChanged(Input input, double direction, double value) {};

		@Override public void buttonPressed(Input input, Button button) {
			if (!isVisible())
				return;
			else if (button == Button.UP)
				onMoveUp();
			else if (button == Button.DOWN)
				onMoveDown();
		}

		@Override public void buttonReleased(Input input, Button button) {};

		@Override public void bindingAccepted(Input input, Button button) {};
		
	}
	
}
